#include "base.h"
#include <cstdio>
#include <windows.h>
#include <windowsx.h>  // 包含 GET_X_LPARAM 宏定义
#include <fcntl.h>    // 包含 _O_U16TEXT 等常量定义
#include <io.h>       // 包含 _setmode 函数声明

#include "stb_image/stb_image.h"

#include "win_display_driver.h"
#include "wnd.h"
#include "button.h"
#include "label.h"

HDC g_hdc = nullptr;
STWnd *root = nullptr;

class Dlg {
public:
    // 构造时传入参数并保存
    Dlg(HDC screenHdc, const STRect& r) 
        : screenHdc(screenHdc), rect(r), hdc(nullptr), hBmp(nullptr),isOpen(false) {}
        // 打开并保存屏幕区域
    bool Open() {
        if (isOpen) return false;

        hdc = CreateCompatibleDC(screenHdc);
        if (!hdc) return false;

        int width = rect.width;
        int height = rect.height;
        hBmp = CreateCompatibleBitmap(screenHdc, width, height);
        if (!hBmp) {
            DeleteDC(hdc);
            hdc = nullptr;
            return false;
        }

        SelectObject(hdc, hBmp);
        BitBlt(hdc, 0, 0, width, height, 
               screenHdc, rect.p.x, rect.p.y, SRCCOPY);

        // BitBlt(screenHdc, rect.p.x, rect.p.y, 
        //         rect.width, rect.height,
        //         hdc, 10, 10, SRCCOPY);
        isOpen = true;
        return true;
    }
    // 恢复并关闭
    void Close() {
        if (!isOpen) return;
        Restore();  // 先恢复画面
        RECT rect;
        // InvalidateRect(screenHdc, &rect, FALSE);
        DeleteObject(hBmp);
        DeleteDC(hdc);
        hdc = nullptr;
        hBmp = nullptr;
        isOpen = false;
    }

    // 单独恢复画面（不关闭）
    void Restore() const {
        if (!isOpen) return;
        BitBlt(screenHdc, rect.p.x, rect.p.y, 
               rect.width, rect.height,
               hdc, 0, 0, SRCCOPY);
    }

    STRect GetRect() {
        return rect;
    }

    ~Dlg() {
        Close();  // 确保资源释放
    }
private:
    HDC screenHdc;   // 保存的屏幕DC
    STRect rect;     // 保存的区域
    HDC hdc;         // 内存DC
    HBITMAP hBmp;    // 位图
    bool isOpen;     // 状态标志
};

void WinDrawStr(const wchar_t* str, const STRect* rect)
{
    int x = 0;
    int y = 0;
    if (rect) {
        x = rect->p.x;
        y = rect->p.y;
    }
    SetBkMode(g_hdc, TRANSPARENT);       // 启用透明背景
    SetTextColor(g_hdc, RGB(0, 0, 255)); // 设置文本颜色为蓝色
    TextOutW(g_hdc, x, y, str, wcslen(str));
}

void WinFillRect(const STRect* rec)
{
    RECT rect = { 0 };
    rect = STRectToRECT(rec);
    HBRUSH m_hBrush = CreateSolidBrush(RGB(255, 0, 0));
    ::FillRect(g_hdc, &rect, m_hBrush);
    DeleteObject(m_hBrush);
}

void WinDrawRect(const STRect* ret)
{// no_brush
    RECT rect = { 0 };
    rect = STRectToRECT(ret);
    HBRUSH hNullBrush = (HBRUSH)GetStockObject(HOLLOW_BRUSH);
    HBRUSH hOldBrush = (HBRUSH)SelectObject(g_hdc, hNullBrush);
    ::Rectangle(g_hdc, rect.left, rect.top, rect.right, rect.bottom);
    // 恢复原有画刷（可选，若后续无其他绘制可省略）
    SelectObject(g_hdc, hOldBrush);
}

STDriverApi g_driver = {
    .DrawStr = WinDrawStr,
    .FillRect = WinFillRect,
    .DrawRect = WinDrawRect,
};

template <class T>
void SafeRelease(T **ppT) {
    if (*ppT) {
        (*ppT)->Release();
        *ppT = nullptr;
    }
}

Dlg *dlg = nullptr;  // 构造时传入参数

class MainWindow : public BaseWindow<MainWindow> {
public:
    MainWindow() : m_hBrush(CreateSolidBrush(RGB(255, 0, 0))) {}
    ~MainWindow() {
        DeleteObject(m_hBrush);
        ReleaseMemoryDC();
    }
    void testImage();

    HDC GetMemHDC() {
        return m_hMemDC;
    }

    LPCWSTR ClassName() const override { return L"CircleWindowClass"; }

    void HandleKeyboardInput(WPARAM wParam) {
        wchar_t str[] = L"abcdefghijk";
        wchar_t str1[] = L"123456789";
        int x = 10;
        int y = 10;
        RECT rect = {0};
        switch (wParam) {
            case 'C': // 按 'C' 键清屏（使用当前背景色）
            {
                dlg->Close();
                // TextOutW(m_hMemDC, x, y, str1, wcslen(str1));
                // InvalidateRect(m_hwnd, NULL, TRUE); // 触发全屏重绘
                // DrawPixelOnBitmap(hwnd, 20, 30, RGB(255, 0, 0), 1); // 绘制红色像素块

                STRect srec = dlg->GetRect();
                RECT dlgRect = STRectToRECT(&srec);
                // rect = {x, y, x + (int)wcslen(str) * 40, y + 60}; // 根据文本大小调整
                InvalidateRect(m_hwnd, &dlgRect, FALSE);
            }
            break;
            case 'B':
                for (int y = 20; y < 40; y++) {
                    for (int x = 20; x < 40; x++) {
                        int dest_offset = (y * m_width + x) * 4; // 每个像素 4 字节（BGRA）
                        BYTE *pPixel = m_pBits + dest_offset;
                        pPixel[0] = 0x89;
                        pPixel[1] = 0xf6;
                        pPixel[2] = 0x53;
                        pPixel[3] = 0x55;
                    }
                }
                rect = {20, 20, 40, 40}; // 根据文本大小调整
                InvalidateRect(m_hwnd, &rect, FALSE);
            break;
            case 'A':
                dlg->Open();
                rect = {x, y, x + (int)wcslen(str) * 40, y + 60}; // 根据文本大小调整
                // wprintf(L"rect.%d--%d--%d-%d\n", rect.left, rect.top, rect.right, rect.bottom);
                // g_driver.DrawStr(str, NULL);
                TextOutW(g_hdc, x, y, str, wcslen(str));
                InvalidateRect(m_hwnd, &rect, FALSE);
                break;
            // case 'B': // 按 'B' 键切换黑色背景
            //     g_BackgroundColor = RGB(0, 0, 0);
            //     {
            //         // 直接操作像素清屏
            //         for (int y = 0; y < WINDOW_HEIGHT; y++) {
            //             for (int x = 0; x < WINDOW_WIDTH; x++) {
            //                 DirectSetPixel(x, y, g_BackgroundColor);
            //             }
            //         }
            //         InvalidateRect(hwnd, NULL, TRUE);
            //     }
            //     break;
            // case 'W': // 按 'W' 键切换白色背景
            //     g_BackgroundColor = RGB(255, 255, 255);
            //     {
            //         // 直接操作像素清屏
            //         for (int y = 0; y < WINDOW_HEIGHT; y++) {
            //             for (int x = 0; x < WINDOW_WIDTH; x++) {
            //                 DirectSetPixel(x, y, g_BackgroundColor);
            //             }
            //         }
            //         InvalidateRect(hwnd, NULL, TRUE);
            //     }
            //     break;
            case VK_ESCAPE: // 按下 ESC 键退出
                PostQuitMessage(0);
                break;
            }
    }
    
    LRESULT HandleMessage(UINT uMsg, WPARAM wParam, LPARAM lParam) {
        switch (uMsg) {
            case WM_CREATE:
                InitializeBuffer();
                return 0;

            case WM_DESTROY:
                PostQuitMessage(0);
                return 0;

            case WM_PAINT:
                OnPaint();
                return 0;

            case WM_SIZE:
                OnResize(wParam, lParam);
                return 0;

            case WM_ERASEBKGND:
                return 1; // 禁用背景擦除

            case WM_LBUTTONDOWN:
                OnLButtonDown(GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam), wParam);
                return 0;

            case WM_MOUSEMOVE:
                OnMouseMove(GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam), wParam);
                return 0;

            case WM_KEYDOWN:
                HandleKeyboardInput(wParam);
            case WM_LBUTTONUP:
                OnLButtonUp();
                return 0;
        }
        return DefWindowProc(m_hwnd, uMsg, wParam, lParam);
    }

private:
    void InitializeBuffer() {
        RECT rc;
        GetClientRect(m_hwnd, &rc);
        CreateMemoryBitmap(rc.right, rc.bottom);
    }

    void ReleaseMemoryDC() {
        if (m_hMemDC) {
            DeleteDC(m_hMemDC);
            m_hMemDC = nullptr;
        }
        if (m_hBitmap) {
            DeleteObject(m_hBitmap);
            m_hBitmap = nullptr;
        }
    }

    void CreateMemoryBitmap(int newWidth, int newHeight) {
        m_width = newWidth;
        m_height = newHeight;
        HDC hdc = GetDC(m_hwnd);

        // 保存旧位图信息
        HDC oldMemDC = m_hMemDC;
        HBITMAP oldBitmap = m_hBitmap;
        BITMAP oldBmpInfo = {};
        if (oldBitmap) {
            GetObject(oldBitmap, sizeof(BITMAP), &oldBmpInfo);
        }

        // 创建新位图
        BITMAPINFO bmi = {};
        bmi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
        bmi.bmiHeader.biWidth = newWidth;
        bmi.bmiHeader.biHeight = -newHeight;
        bmi.bmiHeader.biPlanes = 1;
        bmi.bmiHeader.biBitCount = 32;
        bmi.bmiHeader.biCompression = BI_RGB;

        HDC newMemDC = CreateCompatibleDC(hdc);
        HBITMAP newBitmap = CreateDIBSection(hdc, &bmi, DIB_RGB_COLORS, reinterpret_cast<void**>(&m_pBits), nullptr, 0);
        ReleaseDC(m_hwnd, hdc);

        if (!newBitmap) {
            DeleteDC(newMemDC);
            return;
        }

        SelectObject(newMemDC, newBitmap);

        // 复制旧内容到新位图
        if (oldBitmap) {
            BitBlt(newMemDC, 0, 0, 
                oldBmpInfo.bmWidth, oldBmpInfo.bmHeight,
                oldMemDC, 0, 0, SRCCOPY);
        } else {
            // 首次创建时填充背景
            RECT rc = {0, 0, newWidth, newHeight};
            FillRect(newMemDC, &rc, (HBRUSH)(COLOR_WINDOW + 1));
        }

        // 释放旧资源
        if (oldMemDC) DeleteDC(oldMemDC);
        if (oldBitmap) DeleteObject(oldBitmap);

        // 更新成员变量
        m_hMemDC = newMemDC;
        m_hBitmap = newBitmap;
    }

    void OnPaint() {
        PAINTSTRUCT ps;
        HDC hdc = BeginPaint(m_hwnd, &ps);

        wprintf(L"ps.%d--%d--%d-%d\n", ps.rcPaint.left, ps.rcPaint.top, ps.rcPaint.right, ps.rcPaint.bottom);

        // 双缓冲绘制
        if (m_hMemDC && m_hBitmap) {
            // BOOL BitBlt(
            //     HDC   hdcDest,      // 目标设备上下文句柄
            //     int   nXDest,       // 目标区域左上角的X坐标
            //     int   nYDest,       // 目标区域左上角的Y坐标
            //     int   nWidth,       // 要复制区域的宽度
            //     int   nHeight,      // 要复制区域的高度
            //     HDC   hdcSrc,       // 源设备上下文句柄
            //     int   nXSrc,        // 源区域左上角的X坐标
            //     int   nYSrc,        // 源区域左上角的Y坐标
            //     DWORD dwRop         // 光栅操作码（ROP）
            //   );
            BitBlt(hdc, ps.rcPaint.left, ps.rcPaint.top,
                   ps.rcPaint.right - ps.rcPaint.left,
                   ps.rcPaint.bottom - ps.rcPaint.top, 
                   m_hMemDC, 
                   ps.rcPaint.left, ps.rcPaint.top, 
                   SRCCOPY);
        }
        EndPaint(m_hwnd, &ps);
    }

    void OnResize(WPARAM, LPARAM lParam) {
        CreateMemoryBitmap(LOWORD(lParam), HIWORD(lParam));
        g_hdc = m_hMemDC;
    }

    void OnLButtonDown(int x, int y, DWORD) {
        // 示例：在点击位置绘制
        HDC hdc = m_hMemDC;
        SetPixel(hdc, x, y, RGB(0, 0, 255));
        InvalidateRect(m_hwnd, nullptr, FALSE);
        STKeyEvent ev = {
            .key = 0,
            .type = EVENT_CLICK,
            .point = {
                .x = x,
                .y = y,
            }
        };
        g_wndApi.DispatchEvent(ev);
    }

    void OnMouseMove(int x, int y, DWORD flags) {
        if (flags & MK_LBUTTON) {
            HDC hdc = m_hMemDC;
            SetPixel(hdc, x, y, RGB(0, 255, 0));
            RECT rect = {x, y, x + 1 ,y + 1};
            InvalidateRect(m_hwnd, &rect, FALSE);
        }
    }

    void OnLButtonUp() {
        // 结束绘制操作
    }

    HBRUSH m_hBrush;
    HDC m_hMemDC = nullptr;
    HBITMAP m_hBitmap = nullptr;
    BYTE* m_pBits = nullptr;
    // WinDisplayDriver* m_pDriver = nullptr;

    int m_width = 0;
    int m_height = 0;
};

void MainWindow::testImage()
{
    // 要解码的PNG文件路径
    const char *filepath = "../img/test.png";

    // 解码图像
    int width, height, channels;
    unsigned char *data = stbi_load(filepath, &width, &height, &channels, 0);

    if (data) {
        
        wprintf(L"成功加载图像！\n");
        wprintf(L"尺寸: %dx%d\n", width, height);
        wprintf(L"通道数: %d\n", channels);

        // scale_image(data, width, height, channels, 
        //     g_pBits, WINDOW_WIDTH, WINDOW_HEIGHT, 
        //     SCALE_BILINEAR);
        // 打印第一个像素的RGB值（假设是RGB/RGBA格式）
        if (channels >= 3) {
            wprintf(L"第一个像素的RGB: %d, %d, %d\n",
                   data[0], data[1], data[2]);
        }
        for (int y = 0; y < height && y < m_height; y++) {
            for (int x = 0; x < width && x < m_width; x++) {
                // 计算源图像偏移（基于图片尺寸）
                int src_offset = (y * width + x) * channels;
                
                // 计算目标缓冲区偏移（基于窗口尺寸）
                int dest_offset = (y * m_width + x) * 4; // 每个像素 4 字节（BGRA）
                BYTE *pPixel = m_pBits + dest_offset;

                // 确保源数据不越界（可选）
                if (src_offset + 2 >= width * height * channels) break;

                // 读取 RGB 值（假设 data 是 RGB 或 RGBA 格式）
                unsigned char r = (channels >= 1) ? data[src_offset] : 0;
                unsigned char g = (channels >= 2) ? data[src_offset + 1] : 0;
                unsigned char b = (channels >= 3) ? data[src_offset + 2] : 0;

                // 写入目标缓冲区（BGRA 格式）
                pPixel[0] = b; // Blue
                pPixel[1] = g; // Green
                pPixel[2] = r; // Red
                pPixel[3] = 0xFF; // Alpha（不透明）
            }
        }
        for (int y = m_height / 2 - 120; y < m_height / 2 - 60; y++) {
            for (int x = m_width / 2 - 150; x < m_width / 2; x++) {
                int dest_offset = (y * m_width + x) * 4; // 每个像素 4 字节（BGRA）
                BYTE *pPixel = m_pBits + dest_offset;
                // 写入目标缓冲区（BGRA 格式）12f960
                pPixel[0] = (BYTE)(pPixel[0] * (0x89 / 255.0f) + 0.5f); // Blue
                pPixel[1] = (BYTE)(pPixel[1] * (0xf6 / 255.0f) + 0.5f); // Green
                pPixel[2] = (BYTE)(pPixel[2] * (0x53 / 255.0f) + 0.5f); // Red
                pPixel[3] = (BYTE)(pPixel[3] * (0x55 / 255.0f) + 0.5f);  // Alpha（不透明）
            }
        }
        // 释放内存
        stbi_image_free(data);
    } else {
        wprintf(L"加载失败: %s\n", stbi_failure_reason());
    }
}

void OnButtonClick(STWnd* button, EventType event, void* userdata) {
    const char* msg = (const char*)userdata;
    // printf("按钮 %d 被点击，消息：%s\n", button->id, msg);
    wprintf(L"按钮 %d 被点击，消息：%s\n", button->id, msg);
}

int APIENTRY WinMain(HINSTANCE, HINSTANCE, LPSTR, int nCmdShow) {
    MainWindow win;
    
    SetConsoleOutputCP(CP_UTF8);
    _setmode(_fileno(stdout), _O_U16TEXT);
    wprintf(L"asdf 测试中文.\n");

    if (!win.Create(L"Eng - 测试中文", WS_OVERLAPPEDWINDOW | WS_VISIBLE)) {
        MessageBoxW(nullptr, L"窗口创建失败", L"错误", MB_ICONERROR);
        return 1;
    }
    g_hdc = win.GetMemHDC();

    ShowWindow(win.Window(), nCmdShow);

    STRect area = {10, 10, 300, 50};
    // RECT rect = {10, 10, 300 +10, 50+10};
    // HBRUSH m_hBrush = CreateSolidBrush(RGB(255, 0, 0));
    // ::FillRect(g_hdc, &rect, m_hBrush);
    // DeleteObject(m_hBrush);
    dlg = new Dlg(g_hdc, area);

    // int x = 10;
    // int y = 10;
    // wchar_t str[] = L"12345678";
    // rect = {10, 10, 10 + (int)wcslen(str) * 40, y + 60}; // 根据文本大小调整
    // TextOutW(g_hdc, x, y, str, wcslen(str));

    // dlg->Open();

    // driver.DrawStr(L"123456\0", nullptr);
    win.testImage();

    root = CreateWnd();
    g_roots[0] = root;
    root->driver = &g_driver;
    g_wndApi.SetRect(root, {0, 0, 800, 640});
    STButton *b = CreateButton();
    g_wndApi.SetRect(&(b->base), {400, 300, 100, 30});
    const char* user_msg = "Hello, Event!";
    g_wndApi.SubscribeEvent(&(b->base), EVENT_CLICK, OnButtonClick, (void*)user_msg);

    STLabel *l = CreateLabel();
    g_wndApi.SetRect(&(l->base), {100, 110, 100, 50});
    l->SetText(&(l->base), L"127893");

    g_wndApi.AddChild(root, &(l->base));
    g_wndApi.AddChild(root, &(b->base));

    g_wndApi.RenderTree(root);

    MSG msg = {};
    while (GetMessage(&msg, nullptr, 0, 0)) {
        TranslateMessage(&msg);
        DispatchMessage(&msg);
    }

    delete dlg;
    g_wndApi.DestroyTree(root);

    return static_cast<int>(msg.wParam);
}
